from rest_framework.views import APIView
from apps.inform.models import Inform,InformRead
from django.db.models import Q #用于复杂查询
from apps.inform.serializers import InformSerializer
from django.db.models import Prefetch #用于优化数据库查询
from rest_framework.response import Response
from apps.absent.models import Absent
from apps.absent.serializers import AbsentSerializer
from apps.oaauth.models import OADepartment
from django.db.models import Count #聚合函数
from django.views.decorators.cache import cache_page
from django.utils.decorators import method_decorator #用于对类进行缓存装饰

#对函数进行缓存这样就可以
# @cache_page(60*15) #过期时间
# def cache_demo_view(request):
#     pass
#最新通知的视图
class LatestInformView(APIView):
    #返回最新十条的通知
    @method_decorator(cache_page(60*15)) #对类方法进行缓存装饰
    def get(self, request):
        #返回公共的或用户所在部门能看到的通知
        current_user = request.user
                                #用于多对多关系和反向外键关系
        informs = Inform.objects.prefetch_related(Prefetch( #Prefetch：预先抓取
            "reads", queryset=InformRead.objects.filter(user_id=current_user.uid)), 'departments').filter(Q(public=True) #Q对象进行或查询
                                                                                                          | Q(departments=current_user.department))[:10] #切片操作，前十条
        serializer = InformSerializer(informs,many=True) #序列化验证
        return Response(serializer.data)
class LatestAbsentView(APIView):
    @method_decorator(cache_page(60 * 15))
    def get(self,request):
        #董事会可看到所有考勤，非董事会只能看到本部门的
        current_user = request.user
        queryset = Absent.objects
        if current_user.department.name !='董事会':
            #__表示跨关系模型进行字段查询，表示选择那些 requester 字段所关联的用户模型OAUser的 department_id 等于当前登录用户的 department_id 的记录
            queryset = queryset.filter(requester__department_id=current_user.department_id)
        queryset = queryset.all()[0:10]
        serializer = AbsentSerializer(queryset,many=True)
        return Response(serializer.data)

class DepartmentStaffCountView(APIView):
    @method_decorator(cache_page(60 * 15))
    def get(self,request):
        #annotate在查询集中配合聚合函数使用  Count('staffs')聚合函数，计算每个部门关联的staffs集合的数量
        rows = OADepartment.objects.annotate(staff_count=Count('staffs')).values('name','staff_count') #通过OADepartment模型中反向查询到OAUser模型中related_name='staffs'的外键
        #print(rows)
        #<QuerySet [{'name': '董事会', 'staff_count': 3}, {'name': '产品开发部', 'staff_count': 1}, {'name': '运营部', 'staff_count': 1}, {'name': '销售部', 'staff_count': 1}, {'name': '人事部', 'staff_count': 2}, {'name': '财务部', 'staff_count': 1}]>
        #print('='*10)
        return Response(rows)